<?php

namespace common\behavior;

use common\model\VersionModel;
use common\service\OrderService;
use common\service\ProjectService;
use malkusch\lock\mutex\PHPRedisMutex;
use support\bootstrap\Redis;
use Throwable;

/**
 * 内部版本创建后 同步在甲方创建版本
 */
class VersionCreateInsideVersionCreateBehavior
{
    public function run($params)
    {
        $data = $params['record']['data'];
        if (empty($data['module_id'])
            || $data['module_id'] != module_by_code('task')['id']
            || empty($data['link_id'])
            || $data['link_id'] <= 0
            || empty($data['project_id'])
        ) {
            return;
        }

        // 当前项目是否是外包项目
        $project = ProjectService::getInstance()->getProject($data['project_id'], '*');
        if (empty($project) || $project['type'] != 'outsource') {
            return;
        }
        // 内部任务
        $sourceTask = OrderService::getInstance()->getSourceTaskByTaskId($data['link_id']);
        if (empty($sourceTask)) {
            return;
        }

        $outsideVersion = model(VersionModel::class)->find($data[$params['record']['primary_field']]);
        if (empty($outsideVersion)) {
            return;
        }
        $sourceVersion = model(VersionModel::class)
            ->where([
                'link_id' => $sourceTask['id'],
                'module_id' => $outsideVersion['module_id'],
                'project_id' => $sourceTask['project_id'],
                'number' => $outsideVersion['number'],
            ])
            ->order("id desc")
            ->find();

        // 检查内部项目是否已经存在该任务版本
        if (!empty($sourceVersion)) {
            return;
        }
        try {
            $mutex = new PHPRedisMutex([Redis::connection()->client()], "lock-version_sync_{$outsideVersion['id']}", 10);
            $mutex->synchronized(function () use ($outsideVersion, $sourceTask) {
                // 添加数据
                $newVersionData = $outsideVersion;
                $newVersionData['link_id'] = $sourceTask['id'];
                $newVersionData['tenant_id'] = $sourceTask['tenant_id'];
                $newVersionData['project_id'] = $sourceTask['project_id'];
                $newVersionData['uuid'] = create_uuid();
                unset($newVersionData['module_code'], $newVersionData['project_type'], $newVersionData['id']);
                // 新建版本 or 更新版本信息
                model(VersionModel::class)->add($newVersionData);
                APP_DEBUG && trace('sync version to insource project,action [add]', 'DEBUG');
            });
        } catch (Throwable $e) {
            trace(format_exception_info($e), 'ERR');
        }
    }
}